/**
 * Copyright (c)2005-2007 Matt Kruse (javascripttoolbox.com)
 * 
 * Dual licensed under the MIT and GPL licenses. 
 * This basically means you can use this code however you want for
 * free, but don't claim to have written it yourself!
 * Donations always accepted: http://www.JavascriptToolbox.com/donate/
 * 
 * Please do not link to the .js files on javascripttoolbox.com from
 * your site. Copy the files locally to your server instead.
 *
 *
 * This software has been modified for use with MobileSiteOS by OpenSiteMobile.
 * Please see http://javascripttoolbox.com for the latest "original" version.
 *
 * Note: 'string.write' function is gone. Replaced with a new function 'string.popup'
 */

/*
    javascript object dumper w/dojo integration
*/

dojo.provide("msos.dumper");


msos.dumper.dump = (function(){
    // "Private"
    var maxIterations = 1000;
    var maxDepth = -1;      // Max depth that Dumper will traverse in object
    var iterations = 0;
    var indent = 1;
    var indentText = " ";
    var newline = "\n";
    var object = null;      // Keeps track of the root object passed in
    var properties = null;  // Holds properties of top-level object to traverse - others are ignored
    var page = 1;

    var ObjectName = 'Javascript Object Dump';

    function args(a,index) {
    	var myargs = new Array();
    	for (var i=index; i<a.length; i++) {
    		myargs[myargs.length] = a[i];
    	}
    	return myargs;
    };

    function pad(len) {
    	var ret = "";
    	for (var i=0; i<len; i++) {
    		ret += indentText;
    	}
    	return ret;
    };

    function string(o) {
	var level = 1;
	var indentLevel = indent;
	var ret = "";
	if (arguments.length>1 && typeof(arguments[1])=="number") {
	    level = arguments[1];
	    indentLevel = arguments[2];
	    if (o == object)            { return "[original object]";   }
	} else {
	    iterations = 0;
	    object = o;
	    // If a list of properties are passed in
	    if (arguments.length>1) {
		var list = arguments;
		var listIndex = 1;
		if (typeof(arguments[1])=="object") {
		    list = arguments[1];
		    listIndex = 0;
		}
		for (var i=listIndex; i<list.length; i++) {
		    if (properties == null) { properties = new Object(); }
		    properties[list[i]]=1;
		}
	    }
	  }
        // Just in case, so the script doesn't hang
	if (iterations++>maxIterations) { return "[Max Iterations]";    }
	if (maxDepth != -1
         && level > (maxDepth+1))       { return "...";                 }
	// undefined
	if (typeof(o)=="undefined")     { return "[undefined]";         }
	// NULL
	if (o==null)                    { return "[null]";              }
	// DOM Object
	if (o==window)                  { return "[window]";            }
	if (o==window.document)         { return "[document]";          }
	// FUNCTION
	if (typeof(o)=="function")      { return "[function]";          } 
	// BOOLEAN
	if (typeof(o)=="boolean")       { return (o)?"true":"false";    } 
    	// NUMBER	
	if (typeof(o)=="number")        { return o;                     }
    	// STRING
	if (typeof(o)=="string")        {
            o = msos.common.escape_xml(o);
            o = msos.common.escape_string(o);
            return o;
        } 
	if (typeof(o)=="object")        {
	    if (typeof(o.length)=="number" ) {
                // ARRAY
                if (maxDepth != -1
                 && level > maxDepth)   { return "[ ... ]";             }
                ret = "[";
                for (var i=0; i<o.length;i++) {
		    if (i>0)    { ret += "," +  newline + pad(indentLevel); }
                    else        { ret +=        newline + pad(indentLevel); }
		    ret += string(o[i],level+1,indentLevel-0+indent);
		}
		if (i > 0)      { ret +=        newline + pad(indentLevel-indent); }
		ret += "]";
		return ret;
	    } else {
		// OBJECT
		if (maxDepth != -1
                 && level > maxDepth)   { return "{ ... }";             }
		ret = "{";
		var count = 0;
		for (i in o) {
		    if (o==object && properties!=null && properties[i]!=1) {
						// do nothing with this node
		    } else {
			if (typeof(o[i]) != "unknown") {
			    var processAttribute = true;
			    // Check if this is a DOM object, and if so, if we have to limit properties to look at
			    if (o.ownerDocument|| o.tagName || (o.nodeType && o.nodeName)) {
				processAttribute = false;
				if (i=="tagName" || i=="nodeName" || i=="nodeType" || i=="id" || i=="className") {
				    processAttribute = true;
				}
			    }
                            if (processAttribute) {
				if (count++>0)  { ret += "," +  newline + pad(indentLevel); }
				else            { ret +=        newline + pad(indentLevel); }
				ret += "'" + i + "' => " + string(o[i],level+1,indentLevel-0+i.length+6+indent);
			    }
			}
		      }
		}
                if (count > 0)                  { ret +=        newline + pad(indentLevel-indent); }
		ret += "}";
		return ret;
	      }
	} else                          { return "[unknown]";         }
    };

    string.popup = function(o) {
        var w = msos.common.open_popup_window(
            'debug',
            'obj_dump_' + page,
            'Debug Dump',
            ObjectName,
            string(o,args(arguments,1)),
            djConfig.msos_style,
            djConfig.msos_folder + '/dumper.js'
        );
	if (djConfig.msos_popups_blocked) {
	    alert('Are popup windows being blocked? This page uses a popup for display.');
	    return;
	}
        // Bump page up one for new window
        page++;
        // Reset generic name
        ObjectName = 'Object Dump';
    };

    string.alert = function(o) {
        var temp_text = ObjectName + "\n\n" + string(o,args(arguments,1));
    	alert(temp_text);
        // Reset generic name
        ObjectName = 'Object Dump';
    };

    string.setMaxIterations = function(i) {
	maxIterations = i;
    };

    string.setMaxDepth = function(i) {
    	maxDepth = i;
    };

    string.setObjectName = function(name) {
    	ObjectName = name;
    };

    string.$VERSION = 1.0;
	
    return string;
})();
